package icse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import atae.apli.contexto.AtaeSvCompositeDato;
import atae.apli.contexto.AtaeSvCompositeDatoRegistro;
import atae.apli.contexto.AtaeSvCompositeDatoRegistroIndexado;
import atae.apli.contexto.AtaeSvDato;

public class UtilitarioNacar {

	private AtaeSvCompositeDato contexto;
	private HttpServletRequest request;

	public static UtilitarioNacar getInstance(HttpServletRequest request) 
	{
		UtilitarioNacar instance = null;
		if (request == null) 
		{
			throw new RuntimeException("Parametros pasados a UtilitarioNacar invalidos");
		}
		instance = new UtilitarioNacar();
		instance.setRequest(request);
		return instance;
	}

	public ArrayList obtenerArrayListDeContexto(String clave) {
		AtaeSvCompositeDato registro = getContexto();
		ArrayList listaSalida = new ArrayList();
		AtaeSvDato dato = null;
		HashMap mapa = null;
		try {
			if (registro != null) 
			{
				dato = registro.getElemento(clave);
				if (dato.isCompuesto()) 
				{
					registro = (AtaeSvCompositeDato) dato;
					Iterator itrPadres = registro.getElementos();
					while (itrPadres.hasNext()) 
					{
						AtaeSvDato datoHijo = (AtaeSvDato) itrPadres.next();
						if (datoHijo.isCompuesto()) 
						{
							registro = (AtaeSvCompositeDato) datoHijo;
							Iterator itrHijos = registro.getElementos();
							mapa = new java.util.HashMap();
							while (itrHijos.hasNext()) 
							{
								AtaeSvDato campo = (AtaeSvDato) itrHijos.next();
								String[] a = campo.toString().split(":");
								mapa.put(a[0].trim(), a[1].trim());
							}
							listaSalida.add(mapa);
						}
					}
				}
			} else {
				System.err.println("Not exist data for composite dato");
			}

		} catch (Throwable e) {
			System.err.println("Error execution time: " + e.getMessage() + " traza: "+e.getCause());
		}
		return listaSalida;
	}

	public String obtenerValorDeArray(String nombreLista, int fila, String nombreColumna) 
	{
		String valor = null;
		if (nombreColumna.length() > 0 && nombreLista.length() > 0) 
		{
			ArrayList lista = obtenerArrayListDeContexto(nombreLista);
			if (!lista.isEmpty() && (lista.size() >= fila + 1)) 
			{
				HashMap mapa = (HashMap) lista.get(fila);
				valor = (String) mapa.get(nombreColumna);
			}
		}
		return valor;
	}

	public String[][] getArrayDatos(String clave, String[] contextoCol) 
	{
		return getArrayDatos(clave, contextoCol.length, contextoCol);
	}

	public String[][] getArrayDatos(String clave, int numCol, String[] contextoCol) {
		AtaeSvCompositeDato reg = getContexto();
		AtaeSvDato dato = null;
		try {
			if (reg != null) {
				dato = reg.getElemento(clave);
				if (dato.isCompuesto()) {
					AtaeSvCompositeDatoRegistroIndexado regInd = (AtaeSvCompositeDatoRegistroIndexado) dato;
					if (regInd == null) {
						return null;
					}
					int longitud = regInd.getLongitud();
					String[][] stringRetorno = new String[longitud][];
					AtaeSvCompositeDatoRegistro[] reg1 = new AtaeSvCompositeDatoRegistro[longitud];

					for (int i = 0; i < longitud; i++) {
						reg1[i] = ((AtaeSvCompositeDatoRegistro) regInd.getElemento(i));
						stringRetorno[i] = new String[numCol];
						for (int j = 0; j < numCol; j++) {
							if (contextoCol == null)
								continue;
							AtaeSvDato dato1 = reg1[i].getElemento(contextoCol[j]);

							if ((dato1 != null) && (dato1.getValor() != null))
								stringRetorno[i][j] = trimParcial(dato1.getValor());
							else {
								stringRetorno[i][j] = "".intern();
							}
						}
					}

					return stringRetorno;
				}
			} else {
				System.err.println("Not exist data for composite dato Registro");
			}

		} catch (Throwable e) {
			System.err.println("Error execution time: " + e.getMessage());
		}
		return null;
	}

	private static String trimParcial(String newString) 
	{
		if ((newString != null) && (!newString.equals("".intern()))) 
		{
			String temp = newString.trim();
			if ("".equals(temp)) 
			{
				return temp;
			}
			newString = newString.substring(0, newString.lastIndexOf(temp.charAt(temp.length() - 1)) + 1);
			return newString;
		}
		return "";
	}

	public  AtaeSvCompositeDato getContexto() 
	{
		if (request != null) 
		{
			this.contexto = ((AtaeSvCompositeDato) this.request.getAttribute("contexto"));
		}
		return this.contexto;
	}

	public void setRequest(HttpServletRequest request) 
	{
		this.request = request;
	}

	public HttpServletRequest getRequest() 
	{
		return this.request;
	}
	
	public ArrayList obtenerArrayListDeContexto2(String clave) 
	{	
		AtaeSvCompositeDato reg1 = getContexto();
		ArrayList padres = reg1.getPadres();
		if (padres != null) 
		{
			Iterator iter = padres.iterator();
			Object next = null;
			AtaeSvCompositeDato padre = null;
			while (iter.hasNext()) 
			{
				next = iter.next();
				if ((next != null) && ((next instanceof AtaeSvCompositeDato))) 
				{
					padre = (AtaeSvCompositeDato)next;
					System.out.println("TOSTRING: "+padre.toString()); 
					//this.clave = padre.getClave(this);
				}
			}
		}

		AtaeSvCompositeDato reg = getContexto();
		ArrayList lista = new ArrayList();
		AtaeSvDato dato = null;
		HashMap mapa = null;
		try 
		{
			if (reg != null) 
			{
				dato = reg.getElemento(clave);
				if (dato.isCompuesto()) 
				{
					reg = (AtaeSvCompositeDato) dato;
					Iterator itrPadres = reg.getElementos();
					while (itrPadres.hasNext()) 
					{
						AtaeSvDato datoHijo = (AtaeSvDato) itrPadres.next();
						if (datoHijo.isCompuesto()) 
						{
							reg = (AtaeSvCompositeDato) datoHijo;
							Iterator itrHijos = reg.getElementos();
							mapa = new java.util.HashMap();
							while (itrHijos.hasNext()) 
							{
								AtaeSvDato campo = (AtaeSvDato) itrHijos.next();
								String[] a = campo.toString().split(":");
								mapa.put(a[0].trim(), a[1].trim());
							}
							lista.add(mapa);
						}
					}
				}
			} 
			else 
			{
				System.err.println("Not exist data for composite dato");
			}

		}
		catch (Throwable e) 
		{
			System.err.println("Error execution time: " + e.getMessage());
		}
		return lista;
	}	
	
	public static String[][]  getComboCustom(String[][] array)
	{
		String[][] salida = new String[array.length][2];
		int longitudCodigo = 2;
		for (int i = 0; i < array.length; i++)
		{
			salida[i][0] = 	(array[i][0]).substring(longitudCodigo, 4);
			salida[i][1] = 	array[i][1];
		}				
		return getArrayValid(salida);		
	}
	
	public static String[][] getComboCustom(String[][] array,int colum1, int colum2)
	{
		return getArrayValid(getArrayCustomColumns(array,colum1,colum2));
	}	
	
	private static String[][] getArrayCustomColumns(String[][] array, int cod, int des)
	{
		String[][] salida = new String[array.length][2];
		for (int i = 0; i < array.length; i++) 
		{
			salida[i][0] = 	array[i][cod];
			salida[i][1] = 	array[i][des];
		}
		return salida;
	}
	
	/**
	 * Se tiene una array de esta manera
	 * { "C100","RIMAC","R100","RAMO1", "P100","PRODUCTO1"},
	 * 
	 * @param arrayBase
	 * @return un array de 2 dimensiones de String
	 */
	public static String[][] getFormatArray(String[][] arrayBase)
	{
		return getFormatArray(arrayBase, arrayBase.length);
	}
	
	/**
	 * Se tiene una array de esta manera
	 * { "C100","RIMAC","R100","RAMO1", "P100","PRODUCTO1"},
	 * 
	 * @param arrayBase con todas las filas y columnas
	 * @param columnas se tomara la colummnas que indique
	 * por ejemplo 4, las 4 primeras seran consideradas para formar 2 combos
	 * por ejemplo 6, las 6 primeras seran consideradas para formar 3 combos
	 * teniendo en cuenta que 
	 * por ejemplo 0, tomara todas las columnas 
	 * @return un array de 2 dimensiones de String
	 */
	public static String[][] getFormatArray(String[][] arrayBase, int columnas)
	{
		String[][] arraySalida = (String[][])arrayBase.clone();
		for (int i = 0; i < arrayBase.length; i++) 
		{ 			
			int tamanio = columnas == 0 ? arrayBase[i].length : columnas ;
			String temporal = "";
			for (int j = 0; j < tamanio; j++) 
			{				
				if(j == 0 || j%2 ==0 )
				{
					temporal += arrayBase[i][j];	
					arraySalida[i][j] = temporal;
				}
				else
				{
					arraySalida[i][j] = arrayBase[i][j];
				}
			}
		}
		return arraySalida;
	}
	
	public static void pintaArray(String[][] array) 
	{
		for (int i = 0; i < array.length; i++) 
		{
			String fila = "";
			for (int j = 0; j < array[i].length; j++) 
			{
				fila += array[i][j] + " - ";
			}
			System.out.println(fila);
		}
	}

	
	private static String[][] getArrayValid(String[][] array) 
	{
		Set set = new HashSet();
		for (int i = 0; i < array.length; i++) 
		{
			set.add(new ComboNacar(array[i][0], array[i][1]));
		}
		// lo convierte en array nuevamente
		ComboNacar[] arrayComboNacar = (ComboNacar[]) set.toArray(new ComboNacar[0]);
		String[][] dato = new String[arrayComboNacar.length][2];
		for (int i = 0; i < arrayComboNacar.length; i++) 
		{
			dato[i][0] = arrayComboNacar[i].getCodigo();
			dato[i][1] = arrayComboNacar[i].getDescripcion();
		}
		return dato;
	}
	
}

class ComboNacar{
	private String codigo;
	private String descripcion;
	public ComboNacar(){}
	public ComboNacar(String codigo, String descripcion) {
		super();
		this.codigo = codigo;
		this.descripcion = descripcion;
	}
	public String getCodigo() {
		return codigo;
	}
	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}
	public String getDescripcion() {
		return descripcion;
	}
	public void setDescripcion(String descripcion) {
		this.descripcion = descripcion;
	}
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((codigo == null) ? 0 : codigo.hashCode());
		result = prime * result + ((descripcion == null) ? 0 : descripcion.hashCode());
		return result;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ComboNacar other = (ComboNacar) obj;
		if (codigo == null) {
			if (other.codigo != null)
				return false;
		} else if (!codigo.equals(other.codigo))
			return false;
		if (descripcion == null) {
			if (other.descripcion != null)
				return false;
		} else if (!descripcion.equals(other.descripcion))
			return false;
		return true;
	}

}
